package com.lwl.mini.binding;

import com.lwl.mini.mapping.SqlCommandType;
import com.lwl.mini.reflection.ParamNameResolver;
import com.lwl.mini.session.SqlSession;
import lombok.Data;
import lombok.ToString;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * 存储方法的sql类型和sql语句，方法的返回值类信息，方法的参数列表类信息
 * sql信息不能为空
 * 返回值类信息，即使方法返回值为void，存的也为void.class，不能为空
 * 参数列表类信息可以为空
 *
 * @author lwl
 * @create 2022/4/14 12:37
 */
@Data
@ToString
public class MethodInfo {
    private final Method method;
    private SQLInfo sql;
    private Class<? extends Object> returnType;
    private Class<? extends Object>[] parameterType;
    private final ParamNameResolver paramResolver;



    public MethodInfo(Method method,SQLInfo sql,Class<? extends Object> returnType,Class<? extends Object>[] parameterType){
        this.method = method;
        this.sql = sql;
        this.returnType = returnType;
        this.parameterType = parameterType;
        this.paramResolver = new ParamNameResolver(method);
    }

    public Object execute(SqlSession sqlSession, Object[] args) {
        List result = null;
        SqlCommandType type = sql.getType();
        switch (type) {
            case INSERT: {
                Map<Object, Object> paramMap = convertArgsToSqlCommandParam(args);
                result = sqlSession.update(sql.getSQL(), paramMap, returnType, method);
                break;
            }
            case UPDATE: {
                Map<Object, Object> paramMap = convertArgsToSqlCommandParam(args);
                result = sqlSession.update(sql.getSQL(), paramMap, returnType, method);
                break;
            }
            case DELETE: {
                Map<Object, Object> paramMap = convertArgsToSqlCommandParam(args);
                result = sqlSession.update(sql.getSQL(), paramMap, returnType, method);
                break;
            }
            case SELECT: {
                Map<Object,Object> paramMap =  convertArgsToSqlCommandParam(args);
                result = sqlSession.selectList(sql.getSQL(), paramMap, returnType, method);
                break;
            }
            default:
                throw new BindingException("执行器类型异常," + sql.getType());
        }
        if (List.class.equals(returnType)) {
            return result;
        }else if(result.size() == 1){
            //则返回为实体类
            return  result.get(0);
        }else if(result.size() == 0){
            return null;
        }else{
            throw new BindingException("暂不支持此类型返回");
        }
    }


    private Map<Object, Object> convertArgsToSqlCommandParam(Object[] args) {
        return paramResolver.getNamedParams(args);
    }


}
